home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir24 / morse111.zip / MORSE.ASM < prev    next >
Assembly Source File  |  1994-07-28  |  51KB  |  2,435 lines

  1. name morse
  2. kbright equ 1
  3. kbleft equ 2
  4. kbctrl equ 4
  5. kbalt equ 8
  6. kbscroll equ 10h
  7. kbnum equ 20h
  8. kbcaps equ 40h
  9. kbins equ 80h
  10.  
  11. true equ 1
  12. false equ 0
  13. code SEGMENT public
  14. assume cs:code,ds:code
  15. org 100h
  16. start: jmp transient
  17.  
  18. sound PROC near
  19. ;prequency is in bx
  20.    push  ax
  21.    push  dx
  22.  
  23. or bx,bx
  24. jz sound_done ;frequency 0 no sound
  25. mov ax,34ddh
  26. mov dx,0012h
  27. cmp dx,bx
  28. jnb sound_done
  29. div bx
  30. mov bx,ax
  31. in al,61h
  32. test al,03h
  33. jnz a
  34. or al,03h
  35. out 61h,al
  36. mov al,0b6h
  37.        out 43h,al
  38. a:     mov al,bl
  39.        out 42h,al
  40.        mov al,bh
  41.        out 42h,al
  42. sound_done:pop dx
  43. pop ax
  44. ret
  45. sound endp
  46.  
  47.  
  48. delay proc near
  49. ;duration is in cx
  50. jcxz delay_done;no delay
  51. delay_again:push cx
  52. db 0b9h
  53. timing dw 0 ;mov cx,timing
  54. delay_again1:loop delay_again1
  55. pop cx
  56. loop delay_again
  57. delay_done:ret
  58. delay endp
  59.  
  60. nosound proc near
  61. ;turn off sound
  62. push ax
  63. in al,61h
  64. and al,0fch
  65. out 61h,al
  66. pop ax
  67. ret
  68. nosound endp
  69.  
  70. beep proc near
  71. ;bx contains frequency and cx duration
  72. push cx
  73. call sound
  74. call delay
  75. call nosound
  76. pop cx
  77. ret
  78. beep endp
  79.  
  80. uppercase proc near
  81. ;converts character in al to uppercase, otherwise unchanged
  82. cmp al,'a'
  83. jb exit_uppercase ;character is not lowercase
  84. cmp al,'z'
  85. ja exit_uppercase
  86. sub al,32
  87. exit_uppercase:ret
  88. uppercase endp
  89.  
  90. char_out proc near
  91. ;character should be in al
  92. PUSH BX
  93. PUSH cX
  94. PUSH DX
  95. test byte ptr key_mode,kbalt
  96. jz no_skip
  97. cmp donotskip,false
  98. jne no_skip
  99. mov skip_line,true
  100. jmp char_exit
  101. no_skip:cmp al,0ah ;is character linefeed?
  102. jne not_lf
  103. jmp char_exit
  104. not_lf:cmp al,0dh
  105. jne not_cr
  106. mov al,' '
  107. mov prev_char,al
  108. not_cr:MOV AH,AL ;save al
  109. CMP AL,PREV_CHAR
  110. JNE MULT0 ;not the same as previous character
  111. OR AL,AL
  112. JZ MULT0
  113. CMP AL,'0'
  114. JB MULT_CHAR;NOT A DIGIT
  115. CMP AL,'9'
  116. JBE MULT0 ;CHARACTER IS A DIGIT
  117. MULT_CHAR:INC MULT ;character same as previous char
  118. JMP CONTINUE_CHAR
  119. MULT0:MOV MULT,0
  120. CONTINUE_CHAR:MOV PREV_CHAR,AL
  121. CMP MULT,1
  122. Jbe test_for_space
  123. jmp CHAR_EXIT
  124. test_for_space:CMP AL,' '
  125. JNE CONTINUE_CHAR1
  126. SPACE_CHAR:MOV CX,DOT
  127. CALL DELAY
  128. JMP CHAR_EXIT
  129. CONTINUE_CHAR1:MOV cX,STARTFREQ
  130. mov dx,ditfreq
  131. CMP AL,26
  132. JA not_ctrl_char
  133. ;CHARACTER IS CONTROL A-Z
  134. shr cx,1
  135. SHR DX,1;divide freq by two
  136. ADD AL,64;CHANGE CONTROL CHARACTER TO CORRESPONDING UPPERCASE  CHARACTER
  137. not_ctrl_char:CMP AL,97
  138. JB not_lowercase_char
  139. CMP AL,122
  140. JA not_lowercase_char
  141. SUB AL,32;CONVERT TO UPPERCASE
  142. cmp practice,false
  143. jne not_lowercase_char
  144. CALL LO_FREQ ;make freq lower to identify lowercase
  145. push dx
  146. mov dx,cx
  147. call lo_freq
  148. mov cx,dx
  149. pop dx
  150. not_lowercase_char:CMP AH,91
  151. JB CONTINUE_CHAR4
  152. CMP AH,94
  153. JE CONTINUE_CHAR4
  154. cmp ah,'a'
  155. jae continue_char4
  156. CALL LO_FREQ
  157. push dx
  158. mov dx,cx
  159. call lo_freq
  160. mov cx,dx
  161. pop dx
  162. CONTINUE_CHAR4:CMP AH,123
  163. JB CONTINUE_CHAR5
  164. CMP AH,127
  165. JA CONTINUE_CHAR5
  166. SUB AL,26
  167. cmp ah,127
  168. je continue_char5
  169. CALL LO_FREQ
  170. call lo_freq
  171. push dx
  172. mov dx,cx
  173. call lo_freq
  174. call lo_freq
  175. mov cx,dx
  176. pop dx
  177. CONTINUE_CHAR5:OR AH,AH
  178. JZ CHAR_EXIT
  179. CMP AH,27
  180. JB CONTINUE_CHAR6
  181. CMP AH,32
  182. JB CHAR_EXIT
  183. CONTINUE_CHAR6:CMP AH,128
  184. JAE CHAR_EXIT
  185. sub al,33; exclamation mark is first item in morse_array
  186. xor bh,bh
  187. mov bl,al
  188. mov bl,morse_array[bx]
  189. ;bl contains the encoded morse character
  190. char_start:cmp bl,1
  191. jbe char_done
  192. test bl,1
  193. push bx;save encoded morse character
  194. jz dash
  195. mov bx,DX
  196. call sound
  197. push cx
  198. mov cx,dit
  199. jmp char_a
  200. dash:
  201. mov bx,cX
  202. call sound
  203. push cx
  204. mov cx,dot
  205. char_a:call delay
  206. call nosound
  207. mov cx,weighting
  208. call delay
  209. pop cx
  210. pop bx
  211. shr bl,1
  212. jmp char_start
  213. char_done:;put delay between characters
  214. mov cx,dot
  215. call delay
  216. CHAR_EXIT:POP DX
  217. POP CX
  218. POP BX
  219. ret
  220. char_out endp
  221.  
  222. LO_FREQ PROC NEAR
  223. ;takes frequency in dx, lowers it and returns freq in dx
  224. PUSH AX
  225. push bx
  226. push cx
  227. MOV CX,11
  228. CMP AH, 123
  229. JB LOWERCASE
  230. MOV CL,13
  231. LOWERCASE:
  232. MOV AX,dX;frequency is in ax
  233. xor dx,dx
  234. DIV cX
  235. MOV cX,10
  236. MUL cX
  237. MOV DX,AX
  238. pop cx
  239. pop bx
  240. POP AX
  241. RET
  242. LO_FREQ ENDP
  243.  
  244. test_freq_range proc near
  245. ;new freq is in ax.  if within range put in startfreq
  246. jc exit_test
  247. cmp ax,20
  248. jb exit_test
  249. cmp ax,10000
  250. ja exit_test
  251. mov startfreq,ax
  252. mov ditfreq,ax
  253. exit_test:ret
  254. test_freq_range endp
  255.  
  256. test_speed_range proc near
  257. ;if speed in range then set wpm
  258. jc test_speed_exit ;error occurred in read_decimal, invalid digit
  259. cmp ax,3
  260. jb test_speed_exit
  261. cmp ax,100
  262. ja test_speed_exit
  263. mov words_per_min,ax
  264. call set_speed_wpm
  265. test_speed_exit:ret
  266. test_speed_range endp
  267.  
  268. set_speed_wpm proc near
  269. ;set speed to words_per_min
  270. push ax
  271. push dx
  272. mov ax,32000
  273. xor dx,dx ;msw of divisor is 0
  274. div words_per_min
  275. mov dit,ax
  276. mov weighting,ax
  277. mov dx,3
  278. mul dx
  279. mov dot,ax
  280. mov ax,words_per_min
  281. mov weighting_wpm,ax
  282. mov ratio_wpm,ax
  283. pop dx
  284. pop ax
  285. ret
  286. set_speed_wpm endp
  287.  
  288. set_weighting_wpm proc near
  289. ;sets weighting wpm, should normally be same as words_per_min
  290. push ax
  291. push dx
  292. mov ax,32000
  293. xor dx,dx ;msw of divisor is 0
  294. div weighting_wpm
  295. mov weighting,ax
  296. pop dx
  297. pop ax
  298. ret
  299. set_weighting_wpm endp
  300.  
  301. set_ratio_wpm proc near
  302. ;sets ratio wpm, should normally be same as words_per_min
  303. push ax
  304. push dx
  305. mov ax,32000
  306. xor dx,dx ;msw of divisor is 0
  307. div ratio_wpm
  308. mov dit,ax
  309. pop dx
  310. pop ax
  311. ret
  312. set_ratio_wpm endp
  313.  
  314. check_for_keypress proc near
  315. mov ah,cs:get_key
  316. inc ah ;is key available?
  317. pushf
  318. call dword ptr int16_save
  319. jnz yes_key
  320. clc
  321. ret
  322. yes_key:pushf
  323. mov ah,cs:get_key
  324. call dword ptr int16_save
  325. stc
  326. ret
  327. check_for_keypress endp
  328.  
  329. sweep_frequency proc near
  330. ;sweeps prequency up with ctrl key and down with alt key
  331. ;outputs frequency when space is pressed.
  332. or dl,dl
  333. jne s1
  334. mov bx,startfreq
  335. je s2
  336. s1:mov bx,ditfreq
  337. s2:push bx
  338. call sound ;sound concinuous tone
  339. pop bx
  340. sweep_loop:call check_for_keypress
  341. jc exit_sweep_frequency ;key was pressed
  342. test byte ptr key_mode,kbctrl
  343. jz not_sweep_up
  344. ;control key is pressed so sweep up
  345. inc bx
  346. cmp bx,10000
  347. jbe set_sweep_freq
  348. mov bx,20
  349. set_sweep_freq:push bx
  350. call sound
  351. pop bx
  352. mov cx,6
  353. call delay
  354. not_sweep_up:test byte ptr key_mode,kbalt
  355. jz sweep_loop
  356. dec bx
  357. cmp bx,20
  358. jae set_sweep_freq
  359. mov bx,10000
  360. jmp set_sweep_freq
  361. exit_sweep_frequency:or dl,dl
  362. jne s3
  363. mov startfreq,bx
  364. mov ditfreq,bx
  365. je s4
  366. s3:mov ditfreq,bx
  367. s4:call nosound
  368. mov al,' '
  369. call char_out ;put a space delay before decimal output
  370. mov ax,bx
  371. call output_decimal
  372. ret
  373. sweep_frequency endp
  374.  
  375. sweep_speed proc near
  376. ;select speed by pressing ctrl or alt
  377. sweep_speed_start:
  378. call check_for_keypress
  379. jc sweep_speed_exit ;read the key and exit
  380. mov bx,startfreq
  381. mov cx,dot
  382. call beep
  383. mov cx,dit
  384. call delay
  385. test byte ptr key_mode,kbctrl
  386. jz not_speed_up
  387. cmp words_per_min,100
  388. ja sweep_speed_start
  389. inc words_per_min
  390. call set_speed_wpm
  391. not_speed_up:test byte ptr key_mode,kbalt
  392. jz sweep_speed_start
  393. cmp words_per_min,3
  394. jbe sweep_speed_start
  395. dec words_per_min
  396. call set_speed_wpm
  397. jmp sweep_speed_start
  398. sweep_speed_exit:mov al,' '
  399. call char_out ;put delay before wpm
  400. mov ax,words_per_min
  401. call output_decimal
  402. ret
  403. sweep_speed endp
  404.  
  405. sweep_weighting proc near
  406. sweep_weighting_start:
  407. call check_for_keypress
  408. jc sweep_weighting_exit ;read the key and exit
  409. mov bx,startfreq
  410. mov cx,dot
  411. call beep
  412. mov cx,weighting
  413. call delay
  414. test byte ptr key_mode,kbctrl
  415. jz not_weighting_up
  416. cmp weighting_wpm,100
  417. jae sweep_weighting_start
  418. inc weighting_wpm
  419. call set_weighting_wpm
  420. not_weighting_up:test byte ptr key_mode,kbalt
  421. jz sweep_weighting_start
  422. cmp weighting_wpm,3
  423. jbe sweep_weighting_start
  424. dec weighting_wpm
  425. call set_weighting_wpm
  426. jmp sweep_weighting_start
  427. sweep_weighting_exit:mov al,' '
  428. call char_out
  429. mov ax,weighting_wpm
  430. call output_decimal
  431. ret
  432. sweep_weighting endp
  433.  
  434. sweep_ratio proc near
  435. sweep_ratio_start:call check_for_keypress
  436. jc sweep_ratio_exit ;read the key and exit
  437. mov bx,startfreq
  438. mov cx,dit
  439. call beep
  440. mov cx,weighting
  441. call delay
  442. test byte ptr key_mode,kbctrl
  443. jz not_ratio_up
  444. cmp ratio_wpm,100
  445. jae sweep_ratio_start
  446. inc ratio_wpm
  447. call set_ratio_wpm
  448. not_ratio_up:test byte ptr key_mode,kbalt
  449. jz sweep_ratio_start
  450. cmp ratio_wpm,3
  451. jb sweep_ratio_start
  452. dec ratio_wpm
  453. call set_ratio_wpm
  454. jmp sweep_ratio_start
  455. sweep_ratio_exit:mov al,' '
  456. call char_out
  457. mov ax,ratio_wpm
  458. call output_decimal
  459. ret
  460. sweep_ratio endp
  461.  
  462. sweep_timing proc near
  463. sweep_timing_start:call check_for_keypress
  464. jc sweep_timing_exit ;read the key and exit
  465. mov bx,startfreq
  466. mov cx,dot
  467. call beep
  468. mov cx,dit
  469. call delay
  470. test byte ptr key_mode,kbctrl
  471. jz not_timing_up
  472. cmp timing,1
  473. jbe sweep_timing_start
  474. dec timing
  475. not_timing_up:test byte ptr key_mode,kbalt
  476. jz sweep_timing_start
  477. cmp timing,800h
  478. jae sweep_timing_start
  479. inc timing
  480. jmp sweep_timing_start
  481. sweep_timing_exit:mov al,' '
  482. call char_out
  483. mov ax,timing
  484. call output_decimal
  485. ret
  486. sweep_timing endp
  487.  
  488. read_decimal proc near
  489. ;asciz string in ds:bx carry set if invalid decimal number
  490. ;returns decimal value in ax
  491. push cx
  492. push dx
  493. push si
  494. xor ax,ax ;start with 0
  495. xor ch,ch
  496. mov si,10
  497. decimal_space:mov cl,[bx]
  498. cmp cl,' '
  499. jne decimal_loop ;nonspace character found
  500. inc bx ;skip spaces at beginning
  501. jmp decimal_space
  502. decimal_loop:mov cl,[bx]
  503. cmp cl,' '
  504. jbe decimal_done ;end of string found
  505. cmp cl,'0'
  506. jb decimal_error
  507. cmp cl,'9'
  508. ja decimal_error
  509. mul si
  510. sub cl,'0'
  511. add ax,cx
  512. inc bx
  513. jmp decimal_loop
  514. decimal_done:clc
  515. read_decimal_exit:pop si
  516. pop dx
  517. pop cx
  518. ret
  519. decimal_error:stc
  520. jmp read_decimal_exit
  521. read_decimal endp
  522.  
  523. input_string proc near
  524. ;reads up to a string_len character string from the keyboard
  525. ;stores asciz result in string_buffer
  526. push ax
  527. push bx
  528. push cx
  529. push si
  530. mov bx,offset string_buffer
  531. xor si,si
  532. mov cx,si
  533. get_input_character:call read_a_key
  534. cmp al,0dh
  535. je exit_input
  536. cmp al,8 ;is character a backspace?
  537. jne char_not_backspace
  538. or cl,cl
  539. jne not_beginning_input
  540. push bx
  541. push cx
  542. mov bx,1500
  543. mov cx,1000
  544. call beep
  545. pop cx
  546. pop bx
  547. jmp get_input_character
  548. not_beginning_input:dec cl
  549. dec si
  550. jmp get_input_character
  551. char_not_backspace:cmp cl,string_length
  552. ja get_input_character
  553. call uppercase
  554. mov [bx+si],al
  555. mov mult,0
  556. call char_out
  557. inc si
  558. inc cl
  559. cmp string_length,0
  560. je exit_input
  561. jmp get_input_character
  562. exit_input:xor al,al
  563. mov [bx+si],al
  564. pop si
  565. pop cx
  566. pop bx
  567. pop ax
  568. ret
  569. input_string endp
  570.  
  571. strpos proc near
  572. ;es:di point to main string
  573. ;ds:si point to substring
  574. ;es = ds int this program.
  575. ;returns position of substring in main in ax.  Strings are assumed to be asciiZ strings.
  576. push cx
  577. push dx
  578. cld ;move forward
  579. ;find length of main string
  580. push di ;save start of main string
  581. xor al,al ;scan for 0
  582. mov cx,255 ;maximum length allowed
  583. repne scasb
  584. mov dx,254
  585. sub dx,cx ;dx holds length of main string
  586. mov cl,255 ;maximum length allowed
  587. mov di,si ;put offset of substring in di
  588. repne scasb
  589. sub di,si
  590. mov cx,di
  591. dec cl ;cx contains length of substring
  592. pop di ;restore offset of main
  593. ;if either string has 0 length, return 0
  594. xor ax,ax
  595. or dl,dl
  596. jne main_not_zero
  597. jmp strpos_exit ;main has 0 length
  598. main_not_zero:or cl,cl
  599. jz strpos_exit ;substring has 0 length
  600. ;length of substring should not be greater than length of main
  601. cmp cl,dl
  602. jbe lengths_ok
  603. jmp strpos_exit
  604. lengths_ok:sub dl,cl
  605. inc dl ;limit search of main string
  606. main_string_loop:cmp al,dl
  607. jbe continue_main_string
  608. xor ax,ax ;no match was found
  609. jmp strpos_exit
  610. continue_main_string:
  611. push cx ;save length of substring
  612. push di ;save main offset
  613. push si ;save substring offset
  614. add di,ax ;this is where search begins in main string
  615. repe cmpsb
  616. pop si
  617. pop di ;restore offsets
  618. pop cx ;restore length of substring
  619. jz got_position
  620. inc al
  621. jmp main_string_loop
  622. got_position:inc al
  623. strpos_exit:pop dx
  624. pop cx
  625. ret
  626. strpos endp
  627.  
  628. read_a_key proc near
  629. get_a_key:mov ah,cs:get_key
  630. pushf
  631. call dword ptr int16_save
  632. or al,al
  633. jne got_a_key
  634. pushf
  635. call dword ptr int16_save;ignore function key
  636. jmp get_a_key ;function key was removed, so get more input
  637. got_a_key:ret
  638. read_a_key endp
  639.  
  640. public vid_out
  641. vid_out proc far
  642. cmp cs:inuse,false
  643. je int10_not_inuse
  644. jmp exit_int10
  645. int10_not_inuse:push ax
  646. mov ax,ss
  647. cmp ax,cs:stackseg
  648. pop ax
  649. jne int10_ss_ok
  650. jmp exit_int10
  651. int10_ss_ok:mov cs:inuse,true
  652. mov cs:output_character,ax
  653. mov cs:int10_ss_save,ss
  654. mov cs:int10_sp_save,sp
  655. ;switch ss:sp to morse stack
  656. mov ax,cs
  657. mov ss,ax ;ss = cs
  658. mov sp,cs:int10_sp
  659. mov ax,cs:output_character
  660. push ax
  661. push bx
  662. push cx
  663. push dx
  664. push di
  665. push si
  666. push bp
  667. push ds
  668. push es
  669. mov bx,cs
  670. mov ds,bx ;ds = cs
  671. mov es,bx
  672. cmp ah,2
  673. jne not_setting_cursor
  674. ;application is setting cursor position
  675. or dl,dl ;is application moving cursor to left margin?
  676. jne not_left_margin ;no
  677. mov left_margin,true
  678. jmp int10_done
  679. not_left_margin:mov left_margin,false
  680. jmp int10_done
  681. not_setting_cursor:cmp ah,9
  682. je echo_character
  683. cmp ah,14
  684. je echo_character
  685. ;ah is unknown test int10_quiet
  686. cmp int10_quiet,true
  687. je int10_is_quiet
  688. call output_hex_word
  689. int10_is_quiet:jmp int10_done
  690. echo_character:sti
  691. mov dl,key_mode
  692. and dl,0eh
  693. cmp al,0dh
  694. jne not_return
  695. mov skip_line,false
  696. mov left_margin,false
  697. test dl,kbalt
  698. jz not_return
  699. call make_click
  700. mov prev_char,' '
  701. not_return:cmp dl,0eh
  702. jne skip_quiet_toggle
  703. xor byte ptr quiet_mode,true
  704. skip_quiet_toggle:
  705. cmp quiet_mode,true
  706. jne not_in_quiet_mode
  707. jmp int10_done
  708. not_in_quiet_mode:cmp left_margin,true
  709. jne same_line
  710. mov skip_line,false ;new line
  711. cmp prev_char,' '
  712. je same_line
  713. mov left_margin,0
  714. mov cx,dot
  715. shl cx,1 ;multiply by two
  716. call delay
  717. same_line:
  718. mov cl,skip_char
  719. add cl,skip_line
  720. jne int10_done
  721. cmp practice,false
  722. je NORMAL_CHARACTER
  723. ;while in practice mode, all characters not defined in morse
  724. ;are skipped
  725. cmp al,33
  726. jb NORMAL_CHARACTER
  727. ; if character is !"#$%&'()*+ skip if in practice mode
  728. cmp al,43
  729. jbe int10_done
  730. ;  if character is :;=<> skip if not in practice mode
  731. cmp al,58
  732. jb NORMAL_CHARACTER
  733. cmp al,62
  734. jbe int10_done
  735. CMP AL,'@'
  736. JE INT10_DONE
  737. ; if character is [\]^_ or accent skip if in practice mode
  738. CMP AL,91
  739. JB NORMAL_CHARACTER
  740. CMP AL,96
  741. JBE INT10_DONE
  742. ; if character is {|}~ skip if not in practice mode
  743. CMP AL,123
  744. JB NORMAL_CHARACTER
  745. CMP AL,126
  746. JBE INT10_DONE
  747. NORMAL_CHARACTER:
  748. cmp decimal,false
  749. je no_decimal
  750. xor ah,ah
  751. call output_decimal
  752. jmp int10_done
  753. no_decimal:cmp hex,false
  754. je no_hex
  755. call output_hex_byte
  756. jmp int10_done
  757. no_hex:call char_out
  758. int10_done:cli
  759. pop es
  760. pop ds
  761. pop bp
  762. pop si
  763. pop di
  764. pop dx
  765. pop cx
  766. pop bx
  767. pop ax
  768. mov ss,cs:int10_ss_save
  769. mov sp,cs:int10_sp_save
  770. mov cs:inuse,false
  771. exit_int10: jmp dword ptr cs:int10_off_save
  772. vid_out endp
  773.  
  774. output_decimal proc near
  775. ;converts ax to decimal number and
  776. ;outputs the result in morse or crt if config_flag is true
  777. push cx
  778. push dx
  779. push si
  780. xor cx,cx
  781. mov si,10 ;divide by 10
  782. get_digit:xor dx,dx ;set msw of divisor to 0
  783. div si
  784. add dl,30h ;convert to digit
  785. push dx ;save digits so they can be output in reverse
  786. inc cl
  787. cmp ax,0
  788. jz output_digit
  789. jne get_digit
  790. output_digit:pop ax ;get digit
  791. cmp config_flag,false
  792. je no_config
  793. mov dl,al
  794. mov ah,2
  795. int 21h ;output character
  796. jmp output_decimal_loop
  797. no_config:test byte ptr key_mode,kbalt
  798. jne output_decimal_loop
  799. call char_out
  800. output_decimal_loop:loop output_digit
  801. cmp config_flag,true
  802. je output_decimal_exit
  803. mov al,' '
  804. call char_out ;put space after last digit
  805. output_decimal_exit:pop si
  806. pop dx
  807. pop cx
  808. ret
  809. output_decimal endp
  810.  
  811. output_hex_byte proc near
  812. ;outputs byte in al in hex
  813. push cx
  814. push ax
  815. mov cl,4
  816. shr al,cl
  817. call output_hex_nibble
  818. pop ax
  819. and al,0fh
  820. call output_hex_nibble
  821. mov al,' '
  822. call char_out
  823. pop cx
  824. ret
  825. output_hex_byte endp
  826.  
  827. output_hex_nibble proc near
  828. ;outputs hex nibble in al
  829. add al,30h
  830. cmp al,'9'
  831. jbe hex_out
  832. add al,7
  833. hex_out:call char_out
  834. ret
  835. output_hex_nibble endp
  836.  
  837. output_hex_word proc near
  838. ;outputs ax in hex
  839. push cx
  840. mov cl,12
  841. word_loop:push ax
  842. shr ax,cl
  843. and al,0fh
  844. call output_hex_nibble
  845. pop ax
  846. sub cl,4
  847. jns word_loop
  848. mov al,' '
  849. call char_out
  850. pop cx
  851. ret
  852. output_hex_word endp
  853.  
  854. public int9_in
  855. int9_in proc far
  856. pushf
  857. call dword ptr cs:int9_off_save
  858. cli
  859. push ax
  860. push es
  861. mov ax,40h
  862. mov es,ax
  863. mov al,es:[17h]
  864. mov cs:key_mode,al
  865. pop es
  866. in al,60h
  867. mov cs:scan_code,ax
  868. pop ax
  869. iret
  870. int9_in endp
  871.  
  872. public key_in
  873. key_in proc far
  874. cmp cs:inuse,false
  875. jz int16_not_inuse
  876. jmp exit_int16
  877. int16_not_inuse:
  878. push ax
  879. mov ax,ss
  880. cmp ax,cs:stackseg
  881. pop ax
  882. jne int16_stack_ok
  883. jmp exit_int16
  884. int16_stack_ok:
  885. test ah,0fh
  886. je switch_int16_stack
  887. jmp exit_int16 ;application was not waiting to read a key
  888. switch_int16_stack: ;application is waiting until key is pressed
  889. mov cs:inuse,true
  890. and ah,0f0h
  891. mov cs:get_key,ah
  892. mov cs:int16_ss_save,ss
  893. mov cs:int16_sp_save,sp
  894. ;switch ss:sp to morse stack
  895. mov ax,cs
  896. mov ss,ax ;ss = cs
  897. mov sp,cs:int16_sp
  898. push ax
  899. push bx
  900. push cx
  901. push dx
  902. push di
  903. push si
  904. push bp
  905. push ds
  906. push es
  907. mov bx,cs
  908. mov ds,bx ;ds = cs
  909. mov es,bx
  910. is_key_in_buffer:
  911. mov ah,cs:get_key
  912. or ah,1
  913. pushf
  914. call dword ptr int16_save
  915. jnz key_in_buffer
  916. ;no keys in buffer but scancode from int9 shows if
  917. ;any other key is pressed
  918. cmp scan_code,46h ;scroll lock
  919. jz got_scan
  920. cmp scan_code,4ch ;cursor pad 5
  921. jnz is_key_in_buffer
  922. got_scan:mov extended,true  ;non buffer key was pressed
  923. mov ax,scan_code
  924. jmp process_scan
  925. key_in_buffer:
  926. mov ah,cs:get_key
  927. pushf
  928. call dword ptr int16_save ;get the key
  929. process_scan:cmp prefix,false ;has f10 already been pressed?
  930. jz no_prefix ;no
  931. mov prefix_code,ax ;store key after f10 was pressed
  932. mov key_code,0
  933. jmp process
  934. no_prefix: ;f10 was not the previous key
  935. mov key_code,ax
  936. mov prefix_code,0 ;shows this key was not f10
  937. process: call process_key
  938. mov donotskip,false
  939. mov skip_char,false
  940. mov al,remove
  941. add al,review_mode
  942. or al,al
  943. jz int16_done
  944. mov remove,false
  945. mov extended,false
  946. jmp is_key_in_buffer
  947. int16_done:pop es
  948. pop ds
  949. pop bp
  950. pop si
  951. pop di
  952. pop dx
  953. pop cx
  954. pop bx
  955. pop ax
  956. mov ss,cs:int16_ss_save
  957. mov sp,cs:int16_sp_save
  958. mov cs:inuse,false
  959. mov ax,cs:key_code
  960. iret
  961. exit_int16:jmp dword ptr cs:int16_save
  962. key_in endp
  963.  
  964. process_key proc near
  965. mov skip_line,false
  966. mov skip_char,false ;DO NOT SKIP WHOLE LINES OR CHARACTERS
  967. mov mult,0 ;ALWAYS OUTPUT THE CHARACTER REGARDLESS OF HOW MANY TIMES SAME
  968. ;KEY IS PRESSED
  969. mov donotskip,true
  970. cmp prefix,true
  971. je prefix_on
  972. jmp not_prefix
  973. prefix_on:cmp review_mode,true
  974. jz start_review_mode
  975. jmp not_review_mode
  976. start_review_mode:;AX CONTAINS PREFIX_CODE
  977. cmp ah,1 ;escape
  978. je esc_ins
  979. cmp ah,52h
  980. jne not_esc_ins
  981. esc_ins:mov dx,cursor_pos
  982. mov skip_char,true
  983. call move_cursor ;put cursor back where it was when review was entered
  984. mov skip_char,false
  985. call output_exit
  986. mov review_mode,false
  987. mov found,false
  988. mov prefix,false
  989. jmp ret_1
  990. not_esc_ins:mov dx,review_pos ;current review cursor position
  991. CMP Al,9 ;TAB
  992. JNE NOT_TAB
  993. or dl,7
  994. inc dl
  995. cmp dl,79
  996. jbe tab_line_ok
  997. xor dl,dl ;left margin
  998. inc dh ;next line
  999. cmp dh,24
  1000. jbe tab_line_ok
  1001. call cursor_outof_range
  1002. xor dh,dh ;top line
  1003. tab_line_ok:mov review_pos,dx
  1004. mov skip_char,1
  1005. call move_cursor
  1006. mov skip_char,false
  1007. jmp ret_1
  1008. NOT_TAB:cmp ax,0f00h
  1009. jne not_shift_tab
  1010. test dl,7 ;is cursor already on a tab
  1011. jz sub_shift ;yes it was
  1012. and dl,0f8h
  1013.             jmp shift_tab1
  1014. sub_shift:sub dl,8
  1015. shift_tab1:jns tab_line_ok
  1016. cmp dh,0
  1017. jne shift_line
  1018. call cursor_outof_range
  1019. mov dx,1848h ;lower rightmost tab
  1020. jmp tab_line_ok
  1021. shift_line:dec dh
  1022. mov dl,72
  1023. jmp tab_line_ok
  1024. not_shift_tab:cmp ah,48h
  1025. jne not_review_up
  1026. cmp dh,0
  1027. jne up_line
  1028. call cursor_outof_range
  1029. jmp report_review_character
  1030. up_line:dec dh
  1031. report_review_character:mov review_pos,dx
  1032. mov find_pos,dx
  1033. call move_cursor
  1034. jmp ret_1
  1035. not_review_up:cmp ah,50h
  1036. jne not_review_down
  1037. cmp dh,24
  1038. jb down_line
  1039. call cursor_outof_range
  1040. jmp report_review_character
  1041. down_line:inc dh
  1042. jmp report_review_character
  1043. not_review_down:cmp ah,4bh
  1044. jne not_review_left
  1045. cmp dl,0
  1046. jne left_line
  1047. call cursor_outof_range
  1048. jmp report_review_character
  1049. left_line:dec dl
  1050. jmp report_review_character
  1051. not_review_left:cmp ah,4dh
  1052. jne not_review_right
  1053. cmp dl,79
  1054. jb right_line
  1055. call cursor_outof_range
  1056. jmp report_review_character
  1057. right_line:inc dl
  1058. jmp report_review_character
  1059. not_review_right:cmp ah,47h
  1060. jne not_review_home
  1061. xor dx,dx
  1062. mov found,false
  1063. jmp report_review_character
  1064. not_review_home:CMP AH,49H
  1065. JNE NOT_REVIEW_PAGE_UP
  1066. XOR DH,DH
  1067. JMP REPORT_REVIEW_CHARACTER
  1068. NOT_REVIEW_PAGE_UP:CMP AH,51H
  1069. JNE NOT_REVIEW_PAGE_DOWN
  1070. MOV DH,24
  1071. JMP REPORT_REVIEW_CHARACTER
  1072. NOT_REVIEW_PAGE_DOWN:CMP AH,77H
  1073. JNE NOT_REVIEW_CTRL_HOME
  1074. XOR DL,DL ;BEGINNING OF CURRENT LINE
  1075. JMP REPORT_REVIEW_CHARACTER
  1076. NOT_REVIEW_CTRL_HOME:CMP AH,4FH
  1077. JNE NOT_REVIEW_END
  1078. MOV DX,1800H ;BOTTOM LEFT
  1079. JMP REPORT_REVIEW_CHARACTER
  1080. NOT_REVIEW_END:CMP AH,75H
  1081. JNE NOT_REVIEW_CTRL_END
  1082. MOV DL,79 ;FAR RIGHT OF CURRENT LINE
  1083. JMP REPORT_REVIEW_CHARACTER
  1084. NOT_REVIEW_CTRL_END:CMP AH,73H
  1085. JNE NOT_REVIEW_CTRL_LEFT
  1086. ;MOVE TO PREVIOUS WORD
  1087. MOV SKIP_CHAR,TRUE ;DON'T OUTPUT CHARACTERS UNTIL PREVIOUS WORD IS FOUND
  1088. CALL FIND_PREVIOUS_WORD
  1089. JC FIND_WORD_ERROR
  1090. JMP FIND_WORD_OK
  1091. NOT_REVIEW_CTRL_LEFT:CMP AH,74H
  1092. JNE NOT_REVIEW_CTRL_RIGHT
  1093. ;MOVE TO NEXT WORD
  1094. MOV SKIP_CHAR,TRUE ;DON'T OUTPUT CHARACTERS UNTIL NEXT WORD IS FOUND
  1095. CALL FIND_NEXT_WORD
  1096. JC FIND_WORD_ERROR
  1097. FIND_WORD_OK:MOV SKIP_CHAR,0
  1098. JMP REPORT_REVIEW_CHARACTER
  1099. FIND_WORD_ERROR:MOV BX,2000
  1100. MOV CX,2000
  1101. CALL BEEP
  1102. MOV DX,REVIEW_POS
  1103. CALL MOVE_CURSOR
  1104. JMP RET_1
  1105. NOT_REVIEW_CTRL_RIGHT:cmp al,'?'
  1106. jne not_question
  1107. jmp find
  1108. not_question:;test for a function key
  1109. push ax
  1110. mov bx,fkey_type
  1111. sub ah,fkey_offset[bx]
  1112. CMP AH,3BH
  1113. JB NOT_REVIEW_F_KEYS
  1114. CMP AH,43H
  1115. JBE GOT_REVIEW_F_KEYS
  1116. NOT_REVIEW_F_KEYS:pop ax
  1117. call uppercase
  1118. cmp al,'A'
  1119. jb not_ay
  1120. cmp al,'Y'
  1121. ja not_ay
  1122. sub al,65
  1123. mov dh,al
  1124. xor dl,dl
  1125. mov review_pos,dx
  1126. call review_line
  1127. xor dl,dl
  1128. mov skip_char,true
  1129. call move_cursor
  1130. jmp ret_1
  1131. not_ay:JMP RET_1
  1132. GOT_REVIEW_F_KEYS:pop ax
  1133. mov key_code,ax
  1134. jmp not_prefix
  1135. not_review_mode:cmp ah,1
  1136. jne not_escape1
  1137. call output_exit
  1138. mov prefix,false
  1139. jmp ret_1
  1140. not_escape1:
  1141. CMP AH,52H
  1142. JNE NOT_INSERT_KEY
  1143. MOV BX,OFFSET REVIEW_MODE_MESSAGE
  1144. CALL OUTPUT_MORSE_STRING
  1145. CALL GET_CURSOR_POSITION
  1146. MOV CURSOR_POS,DX
  1147. MOV REVIEW_POS,DX
  1148. MOV REVIEW_MODE,TRUE
  1149. JMP RET_1
  1150. NOT_INSERT_KEY:cmp f10_twice,true
  1151. jne not_f10_twice
  1152. mov f10_twice,false
  1153. mov prefix,false
  1154. mov remove,false
  1155. mov key_code,ax
  1156. ret
  1157. not_f10_twice:cmp al,'\'
  1158. jne not_toggle_quiet
  1159. xor byte ptr quiet_mode,true
  1160. jz quiet_exit
  1161. mov al,127
  1162. call char_out
  1163. quiet_exit:mov prefix,false
  1164. mov remove,true
  1165. ret
  1166. not_toggle_quiet:call uppercase
  1167. cmp al,'S'
  1168. jne not_speed1
  1169. call sweep_speed
  1170. jmp ret_1
  1171. not_speed1:cmp al,'K'
  1172. jne not_type
  1173. mov bx,offset type_message
  1174. call output_morse_string
  1175. type_loop:call read_a_key
  1176. cmp al,27
  1177. je type_done
  1178. mov mult,0
  1179. call char_out
  1180. jmp type_loop
  1181. type_done:call output_exit
  1182. jmp ret_1
  1183. not_type:cmp al,'F'
  1184. jne not_freq1
  1185. xor dl,dl
  1186. call sweep_frequency
  1187. jmp ret_1
  1188. not_freq1:cmp al,'D'
  1189. jne not_freq2
  1190. mov dl,1
  1191. call sweep_frequency
  1192. jmp ret_1
  1193. not_freq2:cmp al,'W'
  1194. jne not_weighting1
  1195. call sweep_weighting
  1196. jmp ret_1
  1197. not_weighting1:cmp al,'R'
  1198. jne not_ratio1
  1199. call sweep_ratio
  1200. not_ratio1:cmp al,'T'
  1201. jne not_timing1
  1202. call sweep_timing
  1203. jmp ret_1
  1204. not_timing1:cmp al,'I'
  1205. jne not10
  1206. xor byte ptr int10_quiet,true
  1207. jne not10
  1208. mov bx,1500
  1209. mov cx,1000
  1210. call beep
  1211. jmp ret_1
  1212. not10:cmp al,'='
  1213. jne not_equal
  1214. inc fkey_type
  1215. and fkey_type,3
  1216. cmp fkey_type,0
  1217. ja not_normal
  1218. mov bx,offset normal_message
  1219. jmp output_state
  1220. not_normal:cmp fkey_type,1
  1221. ja not_ctrl
  1222. mov bx,offset ctrl_message
  1223. jmp output_state
  1224. not_ctrl:cmp fkey_type,2
  1225. ja not_shift
  1226. mov bx,offset shift_message
  1227. jmp output_state
  1228. not_shift:mov bx,offset alt_message
  1229. output_state:call output_morse_string
  1230. jmp ret_1
  1231. not_equal:cmp al,'?'
  1232. je find
  1233. jmp not_find
  1234. find:
  1235. mov bx,2500
  1236. mov cx,1000
  1237. call beep
  1238. cmp found,true
  1239. je skip_find_beep
  1240. mov bx,2000
  1241. mov cx,1000
  1242. call beep
  1243. skip_find_beep:cmp review_mode,false
  1244. jne find_review_on
  1245. ;review is off so find cursor position
  1246. call get_cursor_position
  1247. mov cursor_pos,dx ;store current cursor position
  1248. mov review_pos,dx ;review_pos = cursor_pos
  1249. mov find_pos,dx
  1250. mov review_mode,true ;turn on review mode
  1251. find_review_on:cmp found,true
  1252. je find_initialized ;the previous find was successful
  1253. mov dx,review_pos
  1254. mov find_pos,dx
  1255. mov string_length,40
  1256. call input_string
  1257. lea bx,string_buffer
  1258. cmp byte ptr [bx],0
  1259. jnz find_initialized ;don't search for a null string
  1260. jmp ret_1
  1261. find_initialized:mov dx,find_pos
  1262. cmp dh,24
  1263. ja find_done ;have searched all the screen
  1264. call store_screen_line
  1265. lea si,string_buffer
  1266. lea di,line_string
  1267. call strpos
  1268. or al,al ;did we find a match?
  1269. jz no_find_match ;substring not found in line dh
  1270. dec al
  1271. add find_pos,ax ;get cursor position of match
  1272. mov skip_char,false
  1273. mov dx,find_pos
  1274. mov review_pos,dx
  1275. call move_cursor
  1276. inc find_pos ;the next find won't get the same occurrance
  1277. mov found,true
  1278. jmp ret_1
  1279. no_find_match:inc dh ;try next line
  1280. xor dl,dl
  1281. mov find_pos,dx
  1282. mov ax,20
  1283. mov cl,dh
  1284. xor ch,ch
  1285. push dx
  1286. mul cx
  1287. pop dx
  1288. add ax,600
  1289. mov bx,ax
  1290. mov cx,150
  1291. call beep
  1292. jmp find_initialized
  1293. find_done:mov found,false
  1294. mov dx,review_pos
  1295. mov skip_char,true
  1296. call move_cursor
  1297. not_find:
  1298. comment `
  1299. $1f: begin {output scancode}
  1300. pre_code := 0; scan_code := 0;
  1301. while scan_code <>1 do
  1302. begin
  1303. if scan_code <128 then
  1304. begin
  1305. if scan_code <> pre_code then
  1306. begin
  1307. hex(scan_code);
  1308. line_out(temp);
  1309. end;
  1310. pre_code := scan_code;
  1311. inline($b4/$01/$9c/$2e/$ff/$1e/joff_key/$74/$08);
  1312. inline($b4/$00/$9c/$2e/$ff/$1e/joff_key);
  1313. end;
  1314. end; {while}
  1315.                   remove := true; prefix := false;
  1316. end; {output scan_code}
  1317. else
  1318. prefix := false; remove := true; exit;
  1319. end; {case review is false}
  1320. end; {f10 is false}
  1321. end; {if prefix}
  1322. `
  1323. not_prefix:
  1324. mov ax,key_code
  1325. cmp al,8
  1326. jne not_backspace
  1327. move_left:call get_cursor_position
  1328. cmp dl,0
  1329. je beginning_of_line
  1330. dec dl
  1331. call move_cursor
  1332. mov skip_char,true
  1333. inc dl
  1334. beginning_of_line:call move_cursor
  1335. mov skip_line,true
  1336. mov skip_char,true
  1337. ret
  1338. not_backspace:
  1339. cmp ax,2000h
  1340. jne not_ctrl_alt_d
  1341. test byte ptr key_mode,4
  1342. je not_ctrl_alt_d
  1343. call remove_morse
  1344. ret
  1345. not_ctrl_alt_d: cmp ah,48h ;cursor up
  1346. jne not_up
  1347. call get_cursor_position
  1348. cmp dh,0
  1349. je no_move_up
  1350. dec dh
  1351. call move_cursor
  1352. inc dh
  1353. mov skip_char,true
  1354. no_move_up:call move_cursor
  1355. ret
  1356. not_up:cmp ah,50h ;cursor down
  1357. jne not_down
  1358. call get_cursor_position
  1359. cmp dh,24
  1360. jae no_move_down
  1361. inc dh
  1362. call move_cursor
  1363. dec dh
  1364. mov skip_char,true
  1365. no_move_down:call move_cursor
  1366. ret
  1367. not_down:cmp ah,4bh
  1368. je move_left
  1369. cmp ah,4dh ;cursor right
  1370. jne not_right
  1371. call get_cursor_position
  1372. cmp dl,79
  1373. jae no_move_right
  1374. inc dl
  1375. call move_cursor
  1376. dec dl
  1377. mov skip_char,true
  1378. no_move_right:call move_cursor
  1379. ret
  1380. not_right:cmp ah,52h
  1381. jne not_insert
  1382. test byte ptr key_mode,80h
  1383. je not_insert
  1384. mov bx,offset insert_message
  1385. call output_morse_string
  1386. not_insert:mov bx,fkey_type
  1387. sub ah,fkey_offset[bx]
  1388. cmp ah,3bh
  1389. jne not_f1
  1390. mov bx,offset speed_message
  1391. call output_morse_string
  1392. mov string_length,3
  1393. call input_string
  1394. mov bx,offset string_buffer
  1395. call read_decimal
  1396. jnc change_speed
  1397. mov bx,offset decimal_error_message
  1398. call output_morse_string
  1399. jmp ret_1
  1400. change_speed:call test_speed_range
  1401. jmp ret_1
  1402. not_f1:cmp ah,3ch
  1403. jne not_f2
  1404. mov bx,offset frequency_message
  1405. call output_morse_string
  1406. mov string_length,5
  1407. call input_string
  1408. mov bx,offset string_buffer
  1409. call read_decimal
  1410. jnc change_freq
  1411. mov bx,offset decimal_error_message
  1412. call output_morse_string
  1413. jmp ret_1
  1414. change_freq:call test_freq_range
  1415. jmp ret_1
  1416. not_f2:cmp ah,3dh
  1417. jne not_f3
  1418. mov cl,1
  1419. xor decimal,cl ;toggle decimal
  1420. jz ret_1
  1421. MOV PRACTICE,0
  1422. MOV HEX,0
  1423. MOV BX,OFFSET DECIMAL_MESSAGE
  1424. CALL OUTPUT_MORSE_STRING
  1425. ret_1:mov remove,true
  1426. ret
  1427. not_f3:cmp ah,3eh
  1428. jne not_f4
  1429. mov cl,1
  1430. xor practice,cl ;toggle practice mode
  1431. JZ RET_1
  1432. MOV DECIMAL,0
  1433. MOV HEX,0
  1434. MOV BX,OFFSET PRACTICE_MESSAGE
  1435. CALL OUTPUT_MORSE_STRING
  1436. JMP RET_1
  1437. not_f4:cmp ah,3fh
  1438. jne not_f5
  1439. mov cl,1
  1440. xor hex,cl ;toggle hex mode
  1441. JZ RET_1
  1442. MOV PRACTICE,0
  1443. MOV DECIMAL,0
  1444. MOV BX,OFFSET HEX_MESSAGE
  1445. CALL OUTPUT_MORSE_STRING
  1446. JMP RET_1
  1447. not_f5:cmp ah,40h
  1448. je f6_f7
  1449. cmp ax,4100h
  1450. jne not_f6_f7
  1451. f6_f7:call get_cursor_position
  1452. mov cursor_pos,dx
  1453. cmp ah,41h
  1454. je start_review
  1455. xor dl,dl ;start at beginning of line
  1456. start_review:call review_line
  1457. mov dx,cursor_pos
  1458. mov review_pos,dx
  1459. mov skip_char,true
  1460. call move_cursor
  1461. jmp ret_1
  1462. not_f6_f7:
  1463. cmp ah,42h
  1464. jne not_f8
  1465. call get_cursor_position
  1466. mov al,'L'
  1467. call char_out
  1468. mov al,dh
  1469. inc al
  1470. xor ah,ah
  1471. call output_decimal
  1472. mov al,'C'
  1473. call char_out
  1474. mov al,dl
  1475. inc al
  1476. xor ah,ah
  1477. call output_decimal
  1478. call move_cursor
  1479. jmp ret_1
  1480. not_f8:cmp ah,43h
  1481. jne not_f9
  1482. mov bx,offset linexy_message
  1483. call output_morse_string
  1484. mov string_length,0
  1485. call input_string
  1486. call get_cursor_position
  1487. mov cursor_pos,dx
  1488. mov al,string_buffer
  1489. cmp al,'A'
  1490. jb not_f9
  1491. cmp al,'Z'
  1492. ja not_f9
  1493. sub al,'A'
  1494. mov dh,al
  1495. xor dl,dl
  1496. mov review_pos,dx
  1497. call review_line
  1498. mov skip_char,true
  1499. mov dx,cursor_pos
  1500. call move_cursor
  1501. jmp ret_1
  1502. not_f9:cmp ah,44h
  1503. jne not_f10
  1504. mov prefix,true
  1505. mov bx,2500
  1506. mov cx,1500
  1507. call beep
  1508. jmp ret_1
  1509. not_f10:
  1510. comment `
  1511. if no_mode and (key_code and 255 >0) then char_out(key_code);
  1512. end;{proc_key}
  1513. `
  1514. ret
  1515. process_key endp
  1516.  
  1517. output_exit proc near
  1518. mov bx,offset exit_message
  1519. call output_morse_string
  1520. ret
  1521. output_exit endp
  1522.  
  1523. review_line proc near
  1524. review_line_start:
  1525. test byte ptr key_mode,kbalt
  1526. jne review_line_exit
  1527. call move_cursor
  1528. inc dl
  1529. cmp dl,80
  1530. jl review_line_start
  1531. review_line_exit:ret
  1532. review_line endp
  1533.  
  1534. FIND_NEXT_WORD PROC NEAR
  1535. CALL MOVE_CURSOR
  1536. CMP AL,' '
  1537. JE GET_NEXT_WORD ;GET THE NEXT WORD OR COME TO THE END OF THE SCREEN
  1538. SKIP_CURRENT_WORD:;SKIP THE CURRENT WORD
  1539. INC DL ;MOVE TO THE RIGHT
  1540. CMP DL,79 ;IS CURSOR POSITION VALID FOR THIS LINE
  1541. JB SKIP_SAME_LINE
  1542. CMP DH,24
  1543. JAE FIND_next_ERROR ;END OF SCREEN
  1544. INC DH ;MOVE TO NEXT LINE
  1545. XOR DL,DL ;TO THE LEFT MARGIN
  1546. SKIP_SAME_LINE:CALL MOVE_CURSOR
  1547. CMP AL,' ' ;IF CHAR IS NOT A SPACE THEN WE ARE STILL IN CURRENT WORD
  1548. JNE SKIP_CURRENT_WORD ;CONTINUE TO READ CURRENT WORD
  1549. GET_NEXT_WORD:INC DL
  1550. CMP DL,79
  1551. JBE SAME_NEXT_LINE
  1552. CMP DH,24
  1553. JAE FIND_next_ERROR ;ALREADY AT LOWER RIGHT CORNER
  1554. INC DH
  1555. XOR DL,DL ;MOVE TO THE LEFT ON NEXT LINE
  1556. SAME_NEXT_LINE: CALL MOVE_CURSOR
  1557. CMP AL,' '
  1558. JE GET_NEXT_WORD
  1559. CLC ;INDICATE NO ERROR
  1560. RET
  1561. FIND_next_ERROR:STC ;ERROR
  1562. RET
  1563. FIND_NEXT_WORD ENDP
  1564.  
  1565. FIND_PREVIOUS_WORD PROC NEAR
  1566. mov got_word,false
  1567. cmp dl,0
  1568. jne same_prev_line
  1569. cmp dh,0
  1570. je find_previous_error
  1571. dec dh
  1572. mov dl,80
  1573. same_prev_line:mov skip_char,true;
  1574. r1:dec dl ;go left 1
  1575. call move_cursor
  1576. cmp al,' '
  1577. je no_word
  1578. mov got_word,true
  1579. no_word:cmp dl,0
  1580. jNE same_prev_line1
  1581. cmp got_word,true
  1582. je exit_r1
  1583. cmp dh,0
  1584. je find_previous_error
  1585. dec dh
  1586. mov dl,80
  1587. jmp r1
  1588. same_prev_line1:cmp got_word,false
  1589. je r1
  1590. cmp al,' '
  1591. je exit_r1
  1592. jmp r1
  1593. exit_r1:cmp al,' '
  1594. jne back_word
  1595. inc dl
  1596. back_word:mov skip_char,false
  1597. clc
  1598. ret
  1599. find_previous_error:stc
  1600. ret
  1601. FIND_PREVIOUS_WORD ENDP
  1602.  
  1603. get_cursor_position proc near
  1604. ;returns cursor position in dx
  1605. push ax
  1606. mov ah,0fh
  1607. pushf
  1608. call dword ptr int10_off_save
  1609. mov ah,3
  1610. pushf
  1611. call dword ptr int10_off_save
  1612. pop ax
  1613. ret
  1614. get_cursor_position endp
  1615.  
  1616. move_cursor proc near
  1617. ;moves cursor to position in dx and outputs character
  1618. push dx
  1619. mov ah,0fh
  1620. pushf
  1621. call dword ptr int10_off_save
  1622. pop dx
  1623. mov ah,2
  1624. pushf
  1625. call dword ptr int10_off_save ;move cursor
  1626. mov ah,8
  1627. pushf
  1628. call dword ptr int10_off_save
  1629. cmp skip_char,false
  1630. je output_move_cursor
  1631. ret
  1632. output_move_cursor:cmp decimal,false
  1633. je output_cursor_1
  1634. xor ah,ah
  1635. jmp output_decimal
  1636. output_cursor_1:cmp hex,false
  1637. jz output_cursor_2
  1638. jmp output_hex_byte
  1639. output_cursor_2:jmp char_out
  1640. move_cursor endp
  1641.  
  1642. cursor_outof_range proc near
  1643. mov bx,2500
  1644. mov cx,200
  1645. call beep
  1646. ret
  1647. cursor_outof_range endp
  1648.  
  1649. store_screen_line proc near
  1650. ;stores line in string_buffer starting at cursor position in dx
  1651. push dx
  1652. push di
  1653. cld ;move forward
  1654. mov skip_char,true ;so character won't be output when move_cursor is called
  1655. lea di,line_string ;where screen line will go
  1656. store_screen_loop:call move_cursor
  1657. call uppercase
  1658. stosb
  1659. cmp dl,79
  1660. jae store_screen_exit ;line is complete
  1661. inc dl
  1662. jmp store_screen_loop
  1663. store_screen_exit:xor al,al
  1664. stosb ;terminate string with null
  1665. pop di
  1666. pop dx
  1667. call move_cursor ;restore cursor to original position
  1668. mov skip_char,false
  1669. ret
  1670. store_screen_line endp
  1671.  
  1672. make_click proc near
  1673. cmp click_flag,true
  1674. jne no_click
  1675. mov bx,1500
  1676. mov cx,80
  1677. call beep
  1678. no_click:ret
  1679. make_click endp
  1680.  
  1681. output_morse_string proc near
  1682. ;outputs asciiz string in morse using char_out
  1683. ;string is in ds:bx
  1684. push ax
  1685. string_loop:cmp fkey_type,3
  1686. je skip_alt_test
  1687. test byte ptr key_mode,kbalt
  1688. jne string_done
  1689. skip_alt_test:mov al,[bx]
  1690. cmp al,20h
  1691. jb string_done
  1692. call char_out
  1693. inc bx
  1694. jmp string_loop
  1695. string_done:pop ax
  1696. ret
  1697. output_morse_string endp
  1698.  
  1699. output_string proc near
  1700. ;outputs asciiz string to int10_off_save
  1701. push ax
  1702. push si
  1703. mov si,bx
  1704. string_loop1:mov al,[si]
  1705. cmp al,0
  1706. je string_done1
  1707. mov ah,0eh
  1708. pushf
  1709. call dword ptr int10_off_save
  1710. inc si
  1711. jmp string_loop1
  1712. string_done1:pop si
  1713. pop ax
  1714. ret
  1715. output_string endp
  1716.  
  1717. remove_morse proc near
  1718. ;attempts to remove morse program from memory, saves rebooting
  1719. cli
  1720. push ax
  1721. mov al,127
  1722. call char_out
  1723. mov ax,cs
  1724. mov es,ax ;sets es = cs
  1725. mov ax,4900h
  1726. int 21h ;free memory allocated for morse
  1727. jnc remove_ok ;no error occurred
  1728. ;remove error
  1729. mov bx,offset remove_error_message
  1730. call output_string
  1731. xor dl,dl
  1732. mov cx,1000
  1733. beep1_loop:mov bx,1000
  1734. call beep
  1735. mov bx,1500
  1736. call beep
  1737. inc dl
  1738. cmp dl,5
  1739. jb beep1_loop
  1740. jmp remove_exit
  1741. remove_ok:
  1742. mov bx,offset remove_ok_message
  1743. call output_string
  1744. remove_exit:push ds
  1745. lds dx,dword ptr int10_off_save
  1746. mov ax,2510h
  1747. int 21h ;restore int 10h vector
  1748. lds dx, dword ptr cs:int16_save ;remember ds was changed
  1749. mov ax,2516h
  1750. int 21h ;restore int 16h vector
  1751. lds dx,dword ptr cs:int9_off_save ;remember ds was changed
  1752. mov ax,2509h
  1753. int 21h ;restore int 16h vector
  1754. pop ds
  1755. pop ax
  1756. push ds
  1757. pop es
  1758. int 20h ;exit to dos
  1759. remove_morse endp
  1760.  
  1761. public morse_array,dit,dot,startfreq,prev_char,mult,practice,paragraphs,inuse
  1762. public output_character,stackseg,skip_line,skip_char,args_start
  1763. public int10_seg_save,int10_off_save,int16_save,int9_seg_save
  1764. public int9_off_save
  1765. public int10_ss_save,int10_sp_save,int16_ss_save,int16_sp_save,int9_ss_save
  1766. public int9_sp_save
  1767. public int9_sp,int10_sp,int16_sp
  1768.  
  1769. resident_variables label byte
  1770. morse_array db 52h,24h,28h,7fh,10h,13h,9ch,29h,2dh,35h,2ch,4ch,2eh,55h,36h,20h,21h,23h ;=50
  1771. db 27h,2fh,3fh,3eh,3ch,38h,30h,33h,31h,41h,18h,60h,73h,37h,5h,1eh,1ah,0eh,3h,1bh ;=70
  1772. db 0ch,1fh,7h,11h,0ah,1dh,4h,6h,8h,19h,14h,0dh,0fh,2h,0bh,17h,9h,16h,12h,1ch ;=90
  1773. db 29h,36h,2dh,3dh,2eh,37h,29h,17h,2Dh,3Dh,57h
  1774. dit dw 2000
  1775. dot dw 6000
  1776. weighting dw 2000
  1777. weighting_wpm dw 16
  1778. ratio_wpm dw 16
  1779. startfreq dw 1000;default frequency
  1780. ditfreq dw 1000
  1781. words_per_min dw 16
  1782. PRACTICE dB false
  1783. decimal db false
  1784. hex db false
  1785. f10_twice db false
  1786. fkey_type dw 0
  1787. fkey_offset db 0,35,25,45
  1788. click_flag db true
  1789. get_key db 0
  1790. mult db 0
  1791. PREV_CHAR DB 0
  1792. got_word db ?
  1793. output_character dw ?
  1794. cursor_pos dw ?
  1795. find_pos dw ?
  1796. review_pos dw ?
  1797. remove_ok_message db 'Morse program has been removed from memory',0dh,0ah,0
  1798. insert_message db 'INS',0
  1799. normal_message db 'NORMAL',0
  1800. alt_message db 'ALT',0
  1801. ctrl_message db 'CTRL',0
  1802. shift_message db 'SHIFT',0
  1803. linexy_message db 'A-Y?',0
  1804. speed_message db 'SPEED?',0
  1805. frequency_message db 'FREQ?',0
  1806. DECIMAL_MESSAGE DB 'DEC',0
  1807. HEX_MESSAGE DB 'HEX',0
  1808. PRACTICE_MESSAGE DB 'prac',0
  1809. decimal_error_message db 'ERROR',0
  1810. type_message db 'TYPE',0
  1811. string_length db ?
  1812. string_buffer db 81 dup(?)
  1813. line_string db 81 dup(?)
  1814. remove_error_message db 'An error occurred while removing morse program.  '
  1815. db 'Reboot system',0dh,0ah,0
  1816. int10_off_save dw ?
  1817. int10_seg_save dw ?
  1818. int10_quiet db true
  1819. int16_save dw ?,?
  1820. int9_off_save dw ?
  1821. int9_seg_save dw ?
  1822. int10_sp_save dw ?
  1823. int10_ss_save dw ?
  1824. int16_sp_save dw ?
  1825. int16_ss_save dw ?
  1826. int9_sp_save dw ?
  1827. int9_ss_save dw ?
  1828. int9_sp dw ?
  1829. int10_sp dw ?
  1830. int16_sp dw ?
  1831. paragraphs dw ?
  1832. stackseg dw ?
  1833. inuse db 0
  1834. key_code dw 0
  1835. scan_code dw 0
  1836. prefix_code dw 0
  1837. prefix db 0
  1838. extended dw 0
  1839. remove db 0
  1840. review_mode db false
  1841. key_mode db 0
  1842. quiet_mode db false
  1843. REVIEW_MODE_MESSAGE DB 'RVU',0
  1844. exit_message db 'EXIT',0
  1845. found db false
  1846. skip_line db false
  1847. skip_char db false
  1848. donotskip db false
  1849. left_margin db 0
  1850.  
  1851. transient proc near
  1852. ;save old interrupt vectors
  1853. mov ax,3509h
  1854. int 21h
  1855. mov int9_off_save,bx
  1856. mov int9_seg_save,es
  1857. mov ax,3510h
  1858. int 21h
  1859. mov int10_off_save,bx
  1860. mov int10_seg_save,es
  1861. mov ax,3516h
  1862. int 21h
  1863. mov int16_save,bx
  1864. mov int16_save[2],es
  1865. mov ax,351ch
  1866. int 21h
  1867. mov int1c_off_save,bx
  1868. mov int1c_seg_save,es
  1869. push ds
  1870. pop es ;make es = ds
  1871. call get_args
  1872. cmp cx,1
  1873. jae set_arg_freq
  1874. jmp skip_args ;no arguments were given
  1875. set_arg_freq:mov bx,args_start[0] ;offset for first arguement
  1876. mov al,[bx] ;get first character of first argument
  1877. call uppercase
  1878. cmp al,'A'
  1879. jb got_freq_arg
  1880. cmp al,'C'
  1881. jne not_config
  1882. mov config_flag,true
  1883. jmp skip_args
  1884. not_config:cmp al,'H'
  1885. jne not_help
  1886. call output_help
  1887. not_help:inc bl ;point to next character
  1888. mov skip_greeting,true ;don't display copyright
  1889. cmp al,'S'
  1890. je got_freq_arg
  1891. xor ah,ah
  1892. mov al,[bx] ;should be a digit
  1893. sub al,30h
  1894. cmp al,2
  1895. jae keepres_ok
  1896. mov al,2
  1897. keepres_ok:
  1898. mov keepres_arg,ax
  1899. inc bl
  1900. got_freq_arg:
  1901. call read_decimal
  1902. call test_freq_range
  1903. cmp cx,2
  1904. jb skip_args
  1905. cmp keepres_arg,2
  1906. je skip_args
  1907. mov bx,args_start[2]
  1908. call read_decimal
  1909. call test_speed_range
  1910. cmp cx,3
  1911. jb skip_args
  1912. cmp keepres_arg,3
  1913. je skip_args
  1914. mov bx,args_start[4]
  1915. call read_decimal
  1916. mov weighting_wpm,ax
  1917. call set_weighting_wpm
  1918. cmp cx,4
  1919. jb skip_args ;no ratio
  1920. cmp keepres_arg,4
  1921. je skip_args
  1922. mov bx,args_start[6]
  1923. call read_decimal
  1924. mov ratio_wpm,ax
  1925. call set_ratio_wpm
  1926. cmp cx,5
  1927. jb skip_args ;no timing
  1928. cmp keepres_arg,5
  1929. je skip_args
  1930. mov bx,args_start[8]
  1931. call read_decimal
  1932. mov timing,ax
  1933. skip_args:
  1934. cmp skip_greeting,true
  1935. je transient_continue
  1936. mov dx,offset copyright_message
  1937. mov ah,9
  1938. int 21h
  1939. transient_continue:
  1940. cmp timing,0
  1941. jne skip_set_timing
  1942. ;find timing using int 1c
  1943. mov ax,251ch
  1944. mov dx,offset set_timing
  1945. int 21h
  1946. xor dx,dx ;start with 0
  1947. timing_loop:cmp timer,0
  1948. je timing_loop ;wait for first 1c interrupt before continuing
  1949. mov cx,0310h ;determined by trial and error to give proper timing value
  1950. timing_loop1:
  1951. cmp timer,1
  1952. ja exit_timing
  1953. loop timing_loop1
  1954. inc dx
  1955. jmp timing_loop
  1956. exit_timing:mov timing,dx
  1957. push ds
  1958. mov dx,cs:int1c_off_save
  1959. mov ax,cs:int1c_seg_save
  1960. mov ds,ax
  1961. mov ax,251ch
  1962. int 21h ;restore int 1ch vector
  1963. pop ds
  1964. skip_set_timing:
  1965. cmp config_flag,false
  1966. je no_config1
  1967. call configure_morse
  1968. no_config1:cmp word ptr keepres_arg,0
  1969. je make_resident
  1970. mov bx,keepres_arg
  1971. dec bx ;relative to zero
  1972. shl bx,1 ;times two to index array
  1973. mov bx,args_start[bx]
  1974. call output_morse_string
  1975. int 20h
  1976. make_resident:
  1977. mov bx,offset transient ;find where code ends
  1978. test bx,15 ;is it in the middle of a paragraph
  1979. jz get_sp ;no
  1980. or bl,15
  1981. inc bx ;set bx to paragraph boundary
  1982. get_sp:add bx,512
  1983. mov stackseg,ss
  1984. mov int10_sp,bx
  1985. add bx,512
  1986. mov int16_sp,bx
  1987. add bx,256
  1988. mov int9_sp,bx
  1989. mov cl,4
  1990. shr bx,cl ;divide by 16 to get paragraphs
  1991. inc bx
  1992. mov paragraphs,bx
  1993. mov ax,4900h
  1994. mov bx,2ch
  1995. mov es,[bx] ;es = segment of environment
  1996. int 21h ;free environment
  1997. mov ax,2510h ;set interrupt 10h vector
  1998. mov dx,offset vid_out
  1999. int 21h
  2000. mov ax,2516h
  2001. mov dx,offset key_in
  2002. int 21h
  2003. mov ax,2509h
  2004. mov dx,offset int9_in
  2005. int 21h
  2006. mov ax,3100h
  2007. mov dx,paragraphs
  2008. int 21h ;terminate and stay resident
  2009. transient endp
  2010.  
  2011. get_args proc near
  2012. ;stores arguement offsets into arg_start array
  2013. ;returns the number of args in cx
  2014. xor bx,bx ;start with 0
  2015. mov al,[80h]
  2016. or al,al
  2017. jne args
  2018. jmp args_done ;0 length means no arguements
  2019. args:mov si,81h ;si = offset of first arguement
  2020. skip_arg_spaces: ;argument must begin with nonspace character
  2021. lodsb
  2022. cmp al,' '
  2023. je skip_arg_spaces
  2024. cmp al,0dh
  2025. je args_done
  2026. dec si ;si contains offset of current argument
  2027. mov args_start[bx],si
  2028. inc si
  2029. add bx,2
  2030. args_loop:lodsb
  2031. cmp al,0dh
  2032. je args_done ;found the end
  2033. cmp al,' '
  2034. jne args_loop
  2035. je skip_arg_spaces
  2036. args_done:shr bx,1
  2037. mov cx,bx
  2038. ret
  2039. get_args endp
  2040.  
  2041. set_timing proc near
  2042. inc cs:timer
  2043. jmp dword ptr cs:int1c_off_save
  2044. set_timing endp
  2045.  
  2046. configure_morse proc near
  2047. mov dx,offset configure_message
  2048. mov ah,9
  2049. int 21h
  2050. call read_a_key
  2051. cmp al,1bh
  2052. jne config_continue
  2053. int 20h
  2054. config_continue:
  2055. mov dx,offset crlf
  2056. mov ah,9
  2057. int 21h;go to next line
  2058. mov dx,offset filename
  2059. mov ah,3dh ;open handle
  2060. mov al,2;read/write
  2061. int 21h;open handle
  2062. jnc open_ok
  2063. mov ah,9
  2064. mov dx,offset open_error_message
  2065. int 21h
  2066. int 20h
  2067. open_ok:mov args_start,ax ;save handle
  2068. mov bx,ax
  2069. mov ax,4202h ;seek
  2070. xor cx,cx
  2071. xor dx,dx
  2072. int 21h ;seek to eof to get length of file
  2073. mov cx,offset end_of_segment
  2074. sub cx,100h ;subtract length of psp
  2075. cmp ax,cx ;must be = if file is proper length
  2076. je length_ok
  2077. bad_version:mov dx,offset bad_version_message
  2078. mov ah,9
  2079. int 21h
  2080. int 20h
  2081. length_ok: ;lengths are the same, now check version
  2082. mov dx,offset version_message
  2083. mov si,dx
  2084. sub dx,100h ;get actual file offset by subtracting length of psp
  2085. mov ax,4200h
  2086. xor cx,cx
  2087. int 21h ;seek to bersion_message
  2088. mov ah,3fh ;read
  2089. mov cx,4 ;bytes to read
  2090. mov dx,offset string_buffer
  2091. mov di,dx
  2092. int 21h
  2093. ;compare the two versions which must be the same
  2094. mov bx,di
  2095. mov cl,4
  2096. repe cmpsb
  2097. jne bad_version
  2098. mov bx,offset minimum_freq
  2099. mov cx,startfreq ;get default value
  2100. call get_input_response
  2101. store_config_freq:mov startfreq,ax
  2102. mov ditfreq,ax
  2103. mov bx,offset minimum_speed
  2104. mov cx,words_per_min ;get default value
  2105. call get_input_response
  2106. mov words_per_min,ax
  2107. call set_speed_wpm ;sets dit, dot, ratio, ratio_wpm,  weighting, weighting_wpm
  2108. mov bx,offset minimum_weighting
  2109. mov cx,weighting_wpm ;get default value
  2110. call get_input_response
  2111. mov weighting_wpm,ax
  2112. call set_weighting_wpm
  2113. mov bx,offset minimum_ratio
  2114. mov cx,ratio_wpm ;get default value
  2115. call get_input_response
  2116. mov ratio_wpm,ax
  2117. call set_ratio_wpm
  2118. mov bx,offset minimum_timing
  2119. mov cx,timing ;get default value
  2120. call get_input_response
  2121. mov timing,ax
  2122. mov dx,offset config_practice_message
  2123. mov cl,practice
  2124. call get_yn_response
  2125. mov practice,al
  2126. mov dx,offset config_click_message
  2127. mov cl,click_flag
  2128. call get_yn_response
  2129. mov click_flag,al
  2130. mov dx,offset config_fkey_message
  2131. mov ah,9
  2132. int 21h
  2133. mov ah,1
  2134. int 21h ;get a character
  2135. cmp al,'0'
  2136. jbe key_default
  2137. cmp al,'5'
  2138. jb got_key_type
  2139. key_default: mov al,'1'
  2140. got_key_type:
  2141. sub al,031h
  2142. xor ah,ah
  2143. cmp ax,fkey_type
  2144. je no_fkey_change
  2145. inc config_changed
  2146. no_fkey_change:mov fkey_type,ax
  2147. mov dx,offset config_translation_message
  2148. mov ah,9
  2149. int 21h
  2150. mov ah,1
  2151. int 21h
  2152. call uppercase
  2153. cmp al,'Y'
  2154. jne skip_modify_translation
  2155. call modify_t_table
  2156. skip_modify_translation:
  2157. cmp config_changed,0
  2158. jz config_exit ;no changes so don't write back to disk
  2159. mov dx,offset config_write_message
  2160. mov ah,9
  2161. int 21h
  2162. call read_a_key
  2163. cmp al,27
  2164. je config_exit ;escape was pressed
  2165. config_write:
  2166. config_write1:mov config_flag,false
  2167. mov config_changed,0
  2168. mov bx,args_start ;get file handle
  2169. xor dx,dx
  2170. xor cx,cx ;msw is 0
  2171. mov ax,4200h
  2172. int 21h ;seek to beginning of file
  2173. mov cx,offset end_of_segment
  2174. sub cx,100h ;number of bytes to write
  2175. push cx
  2176. mov dx,100h ;ds:dx points to memory location for write
  2177. mov ah,40h
  2178. int 21h ;write entire file back to disk
  2179. ;the whole file was written because timing comes before resident_variables
  2180. pop cx
  2181. cmp cx,ax ;were the correct number of bytes written?
  2182. jne write_error
  2183. jnc write_ok
  2184. write_error:mov ah,9
  2185. mov dx,offset write_error_message
  2186. int 21h
  2187. int 20h
  2188. write_ok:mov ah,3eh
  2189. mov bx,args_start
  2190. int 21h ;close handle
  2191. mov dx,offset success_message
  2192. mov ah,9
  2193. int 21h
  2194. config_exit:int 20h ;return to dos
  2195. configure_morse endp
  2196.  
  2197. modify_t_table proc near
  2198. mov string_length,8
  2199. modify_t_loop:mov dx,offset mod_char_message
  2200. mov ah,9
  2201. int 21h
  2202. mov ah,1
  2203. int 21h
  2204. cmp al,26
  2205. jbe modify_t_loop ;skip control chars
  2206. cmp al,27
  2207. je modify_t_exit ;escape
  2208. cmp al,'!'
  2209. jb modify_t_loop
  2210. cmp al,128
  2211. jae modify_t_loop ;skip extended graphics chars
  2212. call uppercase
  2213. push ax
  2214. call char_out
  2215. mov mult,0
  2216. pop ax
  2217. mov bl,al
  2218. sub bl,33
  2219. cmp al,123
  2220. jb mod_continue
  2221. sub bl,26 ;lowercase same as upper
  2222. mod_continue:xor bh,bh
  2223. mov ah,9
  2224. mov dx,offset offset_message
  2225. int 21h
  2226. mov ax,bx
  2227. call output_decimal
  2228. mov ah,9
  2229. mov dx,offset letter_message
  2230. int 21h
  2231. mov ah,0ah
  2232. mov dx,offset string_length
  2233. mov si,dx
  2234. int 21h
  2235. mov cl,[si+1]
  2236. or cl,cl
  2237. jz modify_t_loop ;no characters were entered
  2238. inc si
  2239. xor ch,ch
  2240. add si,cx
  2241. mov dl,1
  2242. mod_loop:shl dl,1
  2243. cmp byte ptr [si],'.'
  2244. jne not_period
  2245. or dl,1
  2246. not_period:dec si
  2247. loop mod_loop
  2248. cmp dl,morse_array[bx]
  2249. je modify_t_loop
  2250. inc config_changed
  2251. mov morse_array[bx],dl
  2252. jmp modify_t_loop
  2253. modify_t_exit:ret
  2254. modify_t_table endp
  2255.  
  2256. get_input_response proc near
  2257. ;bx contains offset of minimum value for variable
  2258. ;cx contains default value for variable
  2259. ;returns value to be placed in variable in ax
  2260. retry_input_response:mov dx,bx
  2261. add dx,4 ;offset of message
  2262. mov ah,9
  2263. int 21h ;display message
  2264. mov dx,offset default_message
  2265. mov ah,9
  2266. int 21h
  2267. mov ax,cx ;put default current value in ax
  2268. call output_decimal ;default value
  2269. mov dx,offset paren_message
  2270. mov ah,9
  2271. int 21h
  2272. mov dx,offset string_length
  2273. mov string_length,6
  2274. mov ah,0ah
  2275. int 21h ;get line of input
  2276. cmp string_buffer,0 ;is it a null string
  2277. jne got_input_string ;no, at least 1 character was entered
  2278. mov ax,cx ;variable left unchanged
  2279. ret
  2280. got_input_string:push bx
  2281. mov bx,offset string_buffer
  2282. inc bx ;skip byte containing length of string
  2283. call read_decimal
  2284. pop bx
  2285. jc response_error ;invalid integer was entered
  2286. ;now test ax to see if it is in range
  2287. cmp ax,[bx] ;compare with minimum value
  2288. jb retry_input_response ;below minimum
  2289. cmp ax,[bx+2]
  2290. ja retry_input_response
  2291. inc config_changed ;valid integer in range was entered
  2292. ret
  2293. response_error:mov dx,offset response_error_message
  2294. mov ah,9
  2295. int 21h
  2296. jmp retry_input_response
  2297. get_input_response endp
  2298.  
  2299. get_yn_response proc near
  2300. mov ah,9
  2301. int 21h
  2302. mov dx,offset default_message
  2303. mov ah,9
  2304. int 21h
  2305. mov ah,9
  2306. cmp cl,false
  2307. jne say_yes
  2308. mov dx,offset no_message
  2309. je say_default
  2310. say_yes:mov dx,offset yes_message
  2311. say_default:int 21h
  2312. yn_response:mov ah,1
  2313. int 21h ;get 1 character response
  2314. call uppercase
  2315. cmp al,'Y'
  2316. je set_config_true
  2317. cmp al,0dh
  2318. jne not_config_default
  2319. mov al,cl  ;leave variable unchanged
  2320. jmp no_config_change
  2321. not_config_default:cmp al,'N'
  2322. jne yn_response
  2323. mov al,false
  2324. je test_config_change
  2325. set_config_true:mov al,true
  2326. test_config_change:cmp al,cl
  2327. jz no_config_change
  2328. inc config_changed
  2329. no_config_change:ret
  2330. get_yn_response endp
  2331.  
  2332. output_help proc near
  2333. ;clear screen and put cursor in upper left corner
  2334. mov ax,0600h
  2335. mov bx,7000h
  2336. xor cx,cx ;upper left corner
  2337. mov dx,184fh ;lower right
  2338. pushf
  2339. call dword ptr int10_off_save
  2340. xor dx,dx
  2341. mov skip_char,true
  2342. call move_cursor
  2343. mov dx,offset help_message
  2344. mov ah,9
  2345. int 21h
  2346. int 20h
  2347. output_help endp
  2348.  
  2349. ;the following variables are transient data and are discarded if
  2350. ;morse becomes a tsr
  2351. args_start dw 5 dup(0) ;beginning offset of each argument
  2352. int1c_off_save dw ?
  2353. int1c_seg_save dw ?
  2354. protect_mask db 0
  2355. config_changed db false
  2356. skip_greeting db false
  2357. timer db 0
  2358. help_message db 'Morse.com is a TSR program which echoes screen output in morse code.',0dh,0ah
  2359. db 'useage: morse [c][s][H][frequency] [speed] [ratio] [weighting] [timing]',0dh,0ah
  2360. db 'Frequency can range from 20 to 10,000HZ.  Speed, weighting, and ratio',0dh,0ah
  2361. db 'ranges from 3 to 100 words per minute.',0dh,0ah
  2362. db 'Pressing the ALT key during morse output tells morse to skip the current',0dh,0ah
  2363. db 'line.  Normal output resumes when you release the ALT key.',0dh,0ah
  2364. db 'ALT-CTRL-D Removes morse.com from memory without rebooting.',0dh,0ah
  2365. db '<F1> You are prompted for speed in morse.',0dh,0ah
  2366. db '<F2>  You are prompted in morse to enter frequency.',0dh,0ah
  2367. db '<F3> <F4> and <F5> Toggles decimal, practice and hex mode respectively.',0dh,0ah
  2368. db '<F6>  Output entire cursor line.',0dh,0ah
  2369. db '<F7> Output current line from the cursor to the right.',0dh,0ah
  2370. db '<F8>  Output cursor position and character.',0dh,0ah
  2371. db '<F9>  Output line A-Y in morse.',0dh,0ah
  2372. db '<F10> is used as the first key for the following commands:',0dh,0ah
  2373. db '\  Toggles quiet mode.',0dh,0ah
  2374. db 'F, S, R, W, T sweeps frequency, speed, ratio, weighting and timing',0dh,0ah
  2375. db '<INS>  review mode. <ESC> to exit review mode.'
  2376. db '? Find mode.',0dh,0ah
  2377. db 'K Keyboard mode. <ESC> to exit.$'
  2378. copyright_message db 0dh,0ah,'BLINDOS/PC',0dh,0ah,'Version '
  2379. version_message db '1.11',0dh,0ah,'Copyright 1990-1994 by Randy Formenti  N8KL',0dh,0ah,'$'
  2380. no_message db 'NO) $'
  2381. yes_message db 'YES) $'
  2382. configure_message db 0dh,0ah,'Morse configuration allows you to modify defaults',0dh,0ah
  2383. db 'for frequency, speed, weighting, ratio, timing, practice and clicks.',0dh,0ah
  2384. db 'The Morse default function keys and the morse translation table may also be',0dh,0ah
  2385. db 'modified.',0dh,0ah
  2386. db 'After configuration, MORSE may be run with these new defaults without command',0dh,0ah
  2387. db 'line arguments.',0dh,0ah
  2388. db 'Press <ESC> to abort or any other key to continue. $'
  2389. config_translation_message db 0dh,0ah,'Do you want to modify the Morse '
  2390. db 'translation table (Y/N) $'
  2391. mod_char_message db 0dh,0ah,'Enter character to modify <ESC> to exit: $'
  2392. config_fkey_message db 0dh,0ah,'Choose from the following:',0dh,0ah
  2393. db '1 - F1 through F10',0dh,0ah
  2394. db '2 - CTRL F1 through CTRL F10',0dh,0ah
  2395. db '3 - SHIFT F1 through SHIFT F10',0dh,0ah
  2396. db '4 - ALT F1 through ALT F10',0dh,0ah
  2397. db 'Enter your choice (Default is F1 through F10): $'
  2398. minimum_freq dw 20
  2399. maximum_freq dw 10000
  2400. config_freq_message db 0dh,0ah,'Enter frequency <20-10000>$'
  2401. minimum_speed dw 3
  2402. maximum_speed dw 100
  2403. config_speed_message db 0dh,0ah,'Enter speed <3-100>$'
  2404. minimum_weighting dw 3
  2405. maximum_weighting dw 100
  2406. config_weighting_message db 0dh,0ah,'Enter weighting <3-100>$'
  2407. minimum_ratio dw 3
  2408. maximum_ratio dw 100
  2409. config_ratio_message db 0dh,0ah,'Enter ratio <3-100>$'
  2410. minimum_timing dw 0
  2411. maximum_timing dw 8000h
  2412. config_timing_message db 0dh,0ah,'Enter timing <0-32767>$'
  2413. config_practice_message db 0dh,0ah,'Do you want practice mode on <Y/N>$'
  2414. config_click_message db 0dh,0ah,'Do you want clicks on? <Y/N>$'
  2415. default_message db ' (Default is $'
  2416. paren_message db ') $'
  2417. config_write_message db 0dh,0ah,'Press <ESC> to abort or any other key to'
  2418. db ' write changes to disk.$'
  2419. offset_message db 0dh,0ah,'Offset into translation table is $'
  2420. letter_message db 0dh,0ah,'Enter periods and dashes representing morse for '
  2421. db 'the character: $'
  2422. filename db 'MORSE.COM',0
  2423. crlf db 0dh,0ah,'$'
  2424. open_error_message db 'Unable to open morse.com',0dh,0ah,'$'
  2425. response_error_message db 0dh,0ah,'Invalid number$'
  2426. success_message db 0dh,0ah,'morse has been updated successfully',0dh,0ah,'$'
  2427. bad_version_message db 'Incorrect version.',0dh,0ah,'$'
  2428. write_error_message db 0dh,0ah,'Unable to write morse.com.$'
  2429. config_flag db false
  2430. keepres_arg dw 0
  2431. end_of_segment label byte
  2432. code ends
  2433. end start
  2434.  
  2435.